• Eddie Aftandilian, a developer at GitHub with a background in Java at Google, discusses the implications of Hyrum's Law in the context of software development, particularly focusing on hash ordering. Hyrum's Law, articulated by engineer Hyrum Wright, states that with a sufficient number of users of an API, all observable behaviors of the system will be relied upon by someone, regardless of what is promised in the API contract. This principle has significant consequences for developers, especially when undertaking large-scale migrations. Aftandilian highlights that even with clear documentation advising against reliance on certain implementation-specific behaviors, users often do so inadvertently. This creates challenges when attempting to update systems, as developers may find that their seemingly straightforward migrations are complicated by unexpected dependencies. A key example Aftandilian provides is the iteration order of hash tables. In Java, the `HashMap` class does not guarantee a specific order for its keys and values, as stated in its documentation. However, in practice, the iteration order tends to remain stable over time, leading users to depend on this behavior despite the lack of guarantees. When a team is tasked with upgrading Java versions, they may encounter numerous instances where users have relied on this iteration order, complicating the migration process. Aftandilian identifies several patterns where users might accidentally depend on hash iteration order. One common issue arises with order-dependent tests in unit testing frameworks like JUnit, which historically did not specify the order of test execution. If the execution order remains stable, users may inadvertently write tests that rely on this behavior, leading to fragile test cases. Another issue is over-specified test assertions, where developers might write tests that expect a specific order of elements returned from a method, despite the fact that such an order is not guaranteed. This can lead to tests passing incorrectly, as they are based on an assumption that does not hold true across different implementations. To address these challenges, Aftandilian discusses several approaches. One option is to file bugs against the teams responsible for the code that relies on incorrect assumptions, but this does not resolve the underlying issue. Instead, JUnit opted to specify test execution order to align with the previous behavior of Java, thus providing a temporary solution. A more robust approach is defensive randomization, which aims to eliminate the ability to observe the behavior that users have come to depend on. Aftandilian describes how the Java Development Kit (JDK) was modified to randomize hash iteration order, making it impossible for users to rely on a stable order. This method, inspired by practices in Python and Go, involves using an environment variable to set a random seed, ensuring that the hash iteration order is consistent within a single invocation but varies between invocations. In conclusion, Aftandilian emphasizes that hash iteration order exemplifies Hyrum's Law, illustrating how users will depend on stable behaviors regardless of documentation. The most effective solution is to randomize the iteration order, preventing users from making incorrect assumptions. While it can be frustrating for developers to see others relying on undocumented behaviors, the focus should be on creating systems that minimize the potential for such mistakes. He also references related work in the field, noting that Python and Go have implemented similar randomization strategies, and highlights research addressing the broader issue of underspecified APIs.